package cn.tedu.ai.util;

import cn.tedu.ai.config.AiChatConfig;
import cn.tedu.ai.entity.RoleContent;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import lombok.SneakyThrows;
import okhttp3.HttpUrl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.*;
@Component
public class AiChatUtil {
    @Autowired
    AiChatConfig aiChatConfig;
    public static final JSONObject json = new JSONObject();
    public static List<RoleContent> historyList=new ArrayList<>(); // 对话历史存储集合

    /**
     *
     * 回复消息
     * @param
     * @return
     * @throws MalformedURLException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */

    public   String buildBody(String content){
        /*
        请求体的封装分为三部分
        1.header 两个参数 appId应用的id，uid标识不同用户，这里只有自己故不需要，
        2.parameter参数，里面包含chat参数，chat参数包含domain、temperature、max_tokens三个参数
        domain参数，包含模型类型，这里使用3.5
        temperature参数，包含随机性，这里使用0.5, 最大为1，值越大随机性越高
        max_tokens参数，包含最大长度，[1,8192],根据自己需求选择，值越高回答的字数越多，一个token=1.5个字
        3.payload参数，里面包含message参数，message参数包含text参数，text参数包含历史问题
         text包含role和content两个参数
       role参数表示当前角色，如果值为system表示的是系统背景，如果是user表示当前用户
         */
        JSONObject requestJson=new JSONObject();// 整个请求体
        JSONObject header=new JSONObject();  // header参数
        header.put("app_id",aiChatConfig.getAppId());//
        JSONObject parameter=new JSONObject(); // parameter参数
        JSONObject chat=new JSONObject();
        chat.put("domain","generalv3.5");
        chat.put("temperature",0.5);
        chat.put("max_tokens",8192);
        parameter.put("chat",chat);
        JSONObject payload=new JSONObject(); // payload参数
        JSONObject message=new JSONObject();
        JSONArray text=new JSONArray();
        // 历史问题获取
        if(historyList.size()>0){
            for(RoleContent tempRoleContent:historyList){
                text.add(JSON.toJSON(tempRoleContent));
            }
        }
        // 最新问题
        RoleContent roleContent=new RoleContent();
        roleContent.setRole("user");
        roleContent.setContent(content);
        text.add(JSON.toJSON(roleContent));
        historyList.add(roleContent);
        message.put("text",text);
        payload.put("message",message);
        requestJson.put("header",header);
        requestJson.put("parameter",parameter);
        requestJson.put("payload",payload);
        return requestJson.toString();
    }

    /**
     * 权限校验
     * @return String
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     * @throws MalformedURLException
     */
    @SneakyThrows
    public  String getAuthUrl(){
        URL url = new URL(aiChatConfig.getHostUrl());
        // 时间
        SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
        format.setTimeZone(TimeZone.getTimeZone("GMT"));
        String date = format.format(new Date());
        // 拼接
        String preStr = "host: " + url.getHost() + "\n" +
                "date: " + date + "\n" +
                "GET " + url.getPath() + " HTTP/1.1";
        // System.err.println(preStr);
        // SHA256加密
        Mac mac = Mac.getInstance("hmacsha256");
        SecretKeySpec spec = new SecretKeySpec(aiChatConfig.apiSecret.getBytes(StandardCharsets.UTF_8), "hmacsha256");
        mac.init(spec);
        byte[] hexDigits = mac.doFinal(preStr.getBytes(StandardCharsets.UTF_8));
        // Base64加密
        String sha = Base64.getEncoder().encodeToString(hexDigits);
        // System.err.println(sha);
        // 拼接
        String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", aiChatConfig.getApiKey(), "hmac-sha256", "host date request-line", sha);
        // 拼接地址
        HttpUrl httpUrl = Objects.requireNonNull(HttpUrl.parse("https://" + url.getHost() + url.getPath())).newBuilder().
                addQueryParameter("authorization", Base64.getEncoder().encodeToString(authorization.getBytes(StandardCharsets.UTF_8))).
                addQueryParameter("date", date).
                addQueryParameter("host", url.getHost()).
                build();
        return httpUrl.toString();
    }

    public static boolean canAddHistory(){  // 由于历史记录最大上线1.2W左右，需要判断是能能加入历史
        int history_length=0;
        for(RoleContent temp:historyList){
            history_length=history_length+temp.getContent().length();
        }
        if(history_length>12000){
            historyList.remove(0);
            historyList.remove(1);
            historyList.remove(2);
            historyList.remove(3);
            historyList.remove(4);
            return false;
        }else{
            return true;
        }
    }
}
